package pers.dawnyang.config.security;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.lang3.StringUtils;
import cn.hutool.core.util.HexUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import lombok.extern.slf4j.Slf4j;
import pers.dawnyang.common.util.JsonUtil;

/**
 * 
 * @author dawn
 * @date 2020/12/14
 */
// @Order(1)
// @Component
// @WebFilter(filterName = "Filter1_DecodeFilter", urlPatterns = {"/*"})
@Slf4j
public class DecodeFilter implements Filter {
  private static String aseKey = "1234123412ABCDEF";

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {}

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    HttpServletRequestWrapper requestWrapper =
        new HttpServletRequestWrapper((HttpServletRequest) request) {
          @Override
          public Map<String, String[]> getParameterMap() {
            Map<String, String[]> params = new HashMap<String, String[]>();
            // Map<String, Object> paramMap = new HashMap<>();
            Map<String, String[]> parameterMap = super.getParameterMap();
            System.out.println("flag1:" + parameterMap);
            params.putAll(super.getParameterMap());

            String estxt = request.getParameter("estxt");
            if (!StringUtils.isBlank(estxt)) {
              String requestParam = null;
              String encodeHexStr = HexUtil.encodeHexStr(aseKey);
              byte[] decodeHex = HexUtil.decodeHex(encodeHexStr);
              AES aes = SecureUtil.aes(decodeHex);
              requestParam = aes.decryptStr(estxt);
              params.putAll(changeToFormDateType(dealRequestParamStr(requestParam)));
              params.remove("estxt");
            }
            return Collections.unmodifiableMap(params);

            // return addAllParameters(paramMap);

          }

        };
    String servletPath = requestWrapper.getServletPath();
    System.out.println("decoder:" + servletPath);
    String parameter = requestWrapper.getParameter("userCode");
    System.out.println("decoderParam:" + parameter);
    chain.doFilter(requestWrapper, response);
  }

  @Override
  public void destroy() {

  }

  private Map<String, Object> dealRequestParamStr(String requestParamStr) {
    Map<String, Object> requestDealMap = new HashMap<String, Object>();
    if (requestParamStr.indexOf("&") > 0) {
      requestParamStr = requestParamStr.replaceAll("\"", "");
      try {
        requestParamStr = URLDecoder.decode(requestParamStr, "utf-8");
      } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
      }
      String[] paramArr = requestParamStr.split("&");
      for (String everyParam : paramArr) {
        String[] temp = everyParam.split("=");
        String paramName = temp[0];
        String paramValue = "";
        if (temp.length > 1) {
          paramValue = temp[1];
        }
        requestDealMap.put(paramName, paramValue);
      }
      return requestDealMap;
    }
    return JsonUtil.fromJson(requestParamStr);
  }

  private Map<String, String[]> addAllParameters(Map<String, Object> otherParams) {
    Map<String, String[]> params = new HashMap<String, String[]>();
    for (Map.Entry<String, Object> entry : otherParams.entrySet()) {
      // addParameter(entry.getKey() , entry.getValue());
      String name = entry.getKey();
      Object value = entry.getValue();
      if (value != null) {
        if (value instanceof String[]) {
          params.put(name, (String[]) value);
        } else if (value instanceof String) {
          params.put(name, new String[] {(String) value});
        } else {
          params.put(name, new String[] {String.valueOf(value)});
        }
      }
    }
    return params;
  }

  private Map<String, String[]> addParameter(String name, Object value) {
    Map<String, String[]> params = new HashMap<String, String[]>();
    if (value != null) {
      if (value instanceof String[]) {
        params.put(name, (String[]) value);
      } else if (value instanceof String) {
        params.put(name, new String[] {(String) value});
      } else {
        params.put(name, new String[] {String.valueOf(value)});
      }
    }
    return params;
  }

  private Map<String, String[]> changeToFormDateType(Map<String, Object> params) {
    Map<String, String[]> newMap = new HashMap<>();
    for (Map.Entry<String, Object> mapStr : params.entrySet()) {
      String value = "";
      if (null != mapStr.getValue()) {
        value = mapStr.getValue().toString();
      }
      if (StringUtils.isNotBlank(value)) {
        newMap.put(mapStr.getKey(), new String[0]);
        continue;
      }
      String[] sVal = value.split("::");
      newMap.put(mapStr.getKey(), sVal);
    }
    return newMap;
  }


}
